﻿
// CallDllDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "CallDll.h"
#include "CallDllDlg.h"
#include "afxdialogex.h"
#include "work.h"
#include "oatpp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

CString show;
bool inited = false;//OnInitDialog()是否运行
bool canShow = false; //false不显示主窗口

// CCallDllDlg 对话框
CCallDllDlg::CCallDllDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_CallDll_DIALOG, pParent)
	, mEditValue(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CCallDllDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_BUTTON1, mBtn);
	DDX_Control(pDX, IDC_EDIT1, mEdit);
	DDX_Text(pDX, IDC_EDIT1, mEditValue);
}

BEGIN_MESSAGE_MAP(CCallDllDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON1, &CCallDllDlg::OnClickedButton1)
	ON_WM_SIZE()
	ON_MESSAGE(UM_SHOWTRAY, onShowTray)
	ON_MESSAGE(UM_SHOWTEXT, onShowText)
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	ON_COMMAND(ID_MENUITEM_EXIT, &CCallDllDlg::OnMenuitemExit)
	ON_COMMAND(ID_MENUITEM_SHOW, &CCallDllDlg::OnMenuitemShow)
	ON_COMMAND(ID_MENUITEM_STARTDOWN, &CCallDllDlg::OnMenuitemStartdown)
	ON_COMMAND(ID_MENUITEM_STARTUP, &CCallDllDlg::OnMenuitemStartup)
END_MESSAGE_MAP()


// CCallDllDlg 消息处理程序

BOOL CCallDllDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
/*
	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}
*/
	// 设置此对话框的图标。  当应用程序主窗口不是对话框时，框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	HANDLE mutexHandle = CreateMutex(NULL, TRUE, L"Global\\CallDllSingleInstanceMutex20250109");
	if (GetLastError() == ERROR_ALREADY_EXISTS) {
		// 实例已运行
		AfxMessageBox(L"程序已经运行，可以在系统托盘区找到它！");
		myExit();
	}
	inited = true;
	
	DoTray();
	SendMessage(WM_SIZE);
	CreateLogPath();
	
	::AfxBeginThread(oatpp_main, NULL);

	return TRUE;  // 除非将焦点设置到控件，否则返回 TRUE
}

void CCallDllDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮，则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序，
//  这将由框架自动完成。

void CCallDllDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);		
	}
	else
	{
		CDialogEx::OnPaint();
	}
	if (canShow==false)
	{
		//这一行的作用是启动程序后不显示主窗口
		//ShowWindow(SW_HIDE);
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CCallDllDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CCallDllDlg::OnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
	ShowWindow(SW_HIDE);
}


void CCallDllDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	if (inited)
	{
		CRect rcDlg;
		GetClientRect(rcDlg);

		CRect rcEdit;
		if (::IsWindow(mEdit.m_hWnd)) {
			mEdit.GetWindowRect(rcEdit);
			ScreenToClient(rcEdit);
			rcEdit.top = 0;
			rcEdit.bottom = rcDlg.bottom - 36;
			rcEdit.left = rcDlg.left;
			rcEdit.right = rcDlg.right;
			mEdit.MoveWindow(rcEdit);
		}

		CRect rcBtn;
		if (::IsWindow(mBtn.m_hWnd)) {
			mBtn.GetWindowRect(rcBtn);
			ScreenToClient(rcBtn); /* 我们只是记录大小，或者这2句改为m_BtnOK.GetClientRect(rcBtn);是一样的效果 */
			int nWidth = rcBtn.right - rcBtn.left;
			int nHeight = rcBtn.bottom - rcBtn.top;

			rcBtn.top = rcEdit.bottom + 3;
			rcBtn.bottom = rcBtn.top + nHeight;
			//rcBtn.right = rcDlg.right - 10;
			//rcBtn.left = rcBtn.right-nWidth;
			int w = rcDlg.Width();
			rcBtn.left = (w - nWidth) / 2 + rcDlg.left;
			rcBtn.right = rcBtn.left + nWidth;
			mBtn.MoveWindow(rcBtn);
		}
	}

}

void CCallDllDlg::DoTray()
{
	m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA);
	m_nid.hWnd = this->m_hWnd;
	m_nid.uID = IDR_MAINFRAME;
	m_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
	m_nid.uCallbackMessage = UM_SHOWTRAY;
	//自定义的消息名称 UM_SHOWTASK 头函数中定义为WM_USER+1
	m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
	_tcscpy_s(m_nid.szTip, _T("浏览器助手"));//当鼠标放在上面时，所显示的内容
	Shell_NotifyIcon(NIM_ADD, &m_nid);//在托盘区添加图标
}

LRESULT CCallDllDlg::ShowMainWindow() //wParam接收的是图标的ID，lParam接收的是鼠标的行为
{
	canShow = true;//允许显示主窗口
	this->SendMessage(WM_SIZE);
	this->ShowWindow(SW_SHOWNORMAL);//简单的显示主窗口	
	this->BringWindowToTop();
	this->SetActiveWindow();
	this->SetForegroundWindow();
	return 1;

}

LRESULT CCallDllDlg::onShowTray(WPARAM wParam, LPARAM lParam) //wParam接收的是图标的ID，lParam接收的是鼠标的行为
{
	if (wParam != IDR_MAINFRAME)
		return 1;
	switch (lParam)
	{
	case WM_RBUTTONUP://右键起来时弹出快捷菜单，这里只有一个“关闭”
	{
		CMenu* pTaskMenu, taskMenu;
		CPoint pMousePosition;
		taskMenu.LoadMenu(IDR_SKYNID_MENU);
		pTaskMenu = taskMenu.GetSubMenu(0);
		GetCursorPos(&pMousePosition);
		SetForegroundWindow();
		pTaskMenu->TrackPopupMenu(TPM_RIGHTALIGN, pMousePosition.x, pMousePosition.y, this);
	}
	break;
	case WM_LBUTTONDBLCLK://双击左键的处理
	{
		ShowMainWindow();
	}
	break;
	}
	return 0;
}
LRESULT CCallDllDlg::onShowText(WPARAM wParam, LPARAM lParam) //wParam接收的是图标的ID，lParam接收的是鼠标的行为
{
	mEditValue = show;
	UpdateData(FALSE); // 设置字符串
	mEdit.LineScroll(mEdit.GetLineCount());
	return 1;
}


void CCallDllDlg::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	ShowWindow(SW_HIDE);
	//CDialogEx::OnClose();
}


void CCallDllDlg::OnDestroy()
{
	CDialogEx::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
	::Shell_NotifyIcon(NIM_DELETE, &m_nid);
}


void CCallDllDlg::OnMenuitemExit()
{
	// TODO: 在此添加命令处理程序代码
	myExit();
	//exit(0);
}


void CCallDllDlg::OnMenuitemShow()
{
	// TODO: 在此添加命令处理程序代码
	ShowMainWindow();
}


void CCallDllDlg::OnMenuitemStartdown()
{
	// TODO: 在此添加命令处理程序代码
	int	Response = MessageBox(_T("您确定要关闭开机启动？"), _T("选择消息框"), MB_OKCANCEL | MB_ICONASTERISK);

	if (Response == IDOK)

	{
		// TODO: Add your command handler code here
		HKEY hKey;
		CString strRegPath = _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
		if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, strRegPath, 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS)
		{
			RegDeleteValue(hKey, _T("CallDll"));
			AfxMessageBox(_T("关闭开机启动成功"));
		}
		else
		{
			AfxMessageBox(_T("系统参数错误,不能关闭开机启动"));
		}
		RegCloseKey(hKey);
	}
	else
	{
	}
}


void CCallDllDlg::OnMenuitemStartup()
{
	// TODO: 在此添加命令处理程序代码
	// TODO: Add your command handler code here
	//写入注册表,开机自启动
	HKEY hKey;
	//找到系统的启动项
	LPCTSTR lpRun = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
	//打开启动项Key
	long lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpRun, 0, KEY_WRITE, &hKey);
	if (lRet == ERROR_SUCCESS)
	{

		TCHAR pFileName[MAX_PATH] = { 0 };

		//得到程序自身的全路径

		DWORD dwRet = GetModuleFileName(NULL, pFileName, MAX_PATH);

		//添加一个子Key,并设置值 // 下面的"CallDll"是应用程序名字（不加后缀.exe）

		lRet = RegSetValueEx(hKey, _T("CallDll"), 0, REG_SZ, (BYTE*)pFileName,
			dwRet);

		//关闭注册表

		RegCloseKey(hKey);

		if (lRet != ERROR_SUCCESS)

		{

			AfxMessageBox(_T("系统参数错误,不能开机启动"));

		}
		else
		{
			AfxMessageBox(_T("设置开机启动成功"));

		}
	}
	else
	{
		AfxMessageBox(_T("系统参数错误,不能开机启动"));
	}
}
